package com.scau.meetingbook.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.scau.meetingbook.dto.EnableCancellReservationDTO;
import com.scau.meetingbook.dto.ReservationDTO;
import com.scau.meetingbook.mapper.MeetingRoomsMapper;
import com.scau.meetingbook.mapper.PaymentRecordMapper;
import com.scau.meetingbook.pojo.MeetingRooms;
import com.scau.meetingbook.pojo.PaymentRecord;
import com.scau.meetingbook.pojo.RoomReservations;
import com.scau.meetingbook.mapper.RoomReservationsMapper;
import com.scau.meetingbook.service.RoomReservationsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scau.meetingbook.utils.PayUtil;
import com.scau.meetingbook.utils.TimeConverter;
import com.scau.meetingbook.vo.ResultVO;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;


import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class RoomReservationsServiceImpl extends ServiceImpl<RoomReservationsMapper, RoomReservations> implements RoomReservationsService {

    @Autowired
    private RoomReservationsMapper roomReservationsMapper;

    @Autowired
    private MeetingRoomsMapper meetingRoomsMapper;

    @Autowired
    private PaymentRecordMapper paymentRecordMapper;

    @Autowired
    private TimeConverter  timeConverter;

    @Autowired
    private PayUtil payUtil;

    @Override
    public ResultVO insertRoomReservations(RoomReservations roomReservations) throws Exception {
        roomReservationsMapper.insert(roomReservations);
        return ResultVO.success(null);
    }

    @Override
    public ResultVO<RoomReservations> getRoomReservationsById(Integer id) throws Exception {
        return ResultVO.success(null, roomReservationsMapper.selectById(id));
    }

    @Override
    public ResultVO updateRoomReservationsById(RoomReservations roomReservations) throws Exception {
        roomReservationsMapper.updateById(roomReservations);
        return ResultVO.success(null);
    }

    @Override
    public ResultVO deleteRoomReservationsById(Integer id) throws Exception {
        roomReservationsMapper.deleteById(id);
        return ResultVO.success(null);
    }

    @Override
    public ResultVO createReservation(ReservationDTO reservationDTO) {
        //  生成订单ID
        String reservationId = UUID.randomUUID().toString().replace("-","");
        RoomReservations roomReservations = new RoomReservations();
        roomReservations.setReservationId(reservationId);

        roomReservations.setRoomId(reservationDTO.getRoomId());
        roomReservations.setUserId(reservationDTO.getUserId());
        roomReservations.setReservationDate(reservationDTO.getDate());

        Date startTime = timeConverter.convertStringToDate(reservationDTO.getStartTime());
        roomReservations.setStartTime(startTime);

        Date endTime = timeConverter.convertStringToDate(reservationDTO.getEndTime());
        roomReservations.setEndTime(endTime);

        roomReservations.setParticipants(reservationDTO.getPerosonNum());
        roomReservations.setReservationStatus("pending");

        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 添加30分钟
        LocalDateTime paymentDeadline = now.plusMinutes(30);
        // 转换为Date类型
        Date paymentDeadlineDate = Date.from(paymentDeadline.atZone(ZoneId.systemDefault()).toInstant());
        roomReservations.setPaymentDeadline(paymentDeadlineDate);

        RoomReservations one = roomReservationsMapper.selectOne(new QueryWrapper<RoomReservations>().eq("reservation_date", reservationDTO.getDate())
                .eq("room_id", reservationDTO.getRoomId())
                .eq("user_id", reservationDTO.getUserId())
                .eq("start_time", startTime)
                .eq("end_time", endTime)
                .eq("participants", reservationDTO.getPerosonNum()));

        if(one != null){
            throw new RuntimeException("订单已存在");
        }else{
            roomReservationsMapper.insert(roomReservations);
        }

        return ResultVO.success(null,reservationId);
    }

    @Transactional
    @Override
    public String payReservation(String reservationId) throws AlipayApiException {
        RoomReservations roomReservations = roomReservationsMapper.selectOne(new QueryWrapper<RoomReservations>().eq("reservation_id", reservationId));
        if (roomReservations != null) {
            if(roomReservations.getReservationStatus().equals("pending")){
                Double hours = roomReservations.getDurationHours();
                MeetingRooms roomId = meetingRoomsMapper.selectOne(new QueryWrapper<MeetingRooms>().eq("room_id", roomReservations.getRoomId()));
                BigDecimal pay = roomId.getHourlyRentalPrice().multiply(BigDecimal.valueOf(hours));
                //TODO支付
                //生成订单号（支付宝的要求？）
                String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
                String user = UUID.randomUUID().toString().replace("-", "").toUpperCase();
                String OrderNum = time + user;
                float oderValue = pay.floatValue();

                // 保存订单信息到数据库（用于后续验证）
                createPaymentRecord(OrderNum, reservationId, BigDecimal.valueOf(oderValue));

                return payUtil.sendRequestToAlipay(OrderNum, oderValue, roomId.getName());
            }else{
                return null;
            }
        }else{
            return null;
        }
    }

    // 创建支付记录
    private void createPaymentRecord(String outTradeNo, String reservationId, BigDecimal amount) {
        PaymentRecord record = new PaymentRecord();
        record.setOutTradeNo(outTradeNo);
        record.setReservationId(reservationId);
        record.setAmount(amount);
        record.setStatus("WAITING_PAY"); // 等待支付
        record.setCreateTime(new Date());
        paymentRecordMapper.insert(record);
    }

    @Override
    public ResultVO<List<EnableCancellReservationDTO>> getEnableCancellReservations(Integer userId) {
        // 计算24小时后的时间点
        Date twentyFourHoursAgo = new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000);

        QueryWrapper<RoomReservations> queryWrapper = new QueryWrapper<>();
        queryWrapper.and(wrapper -> wrapper
                .eq("reservation_status", "confirmed")
                .or()
                .eq("reservation_status", "pending")
        ).eq("user_id", userId);

        List<RoomReservations> roomReservations = roomReservationsMapper.selectList(queryWrapper);

        List<RoomReservations> collect = roomReservations.stream().map(item -> {
            if (item.getFullStartDateTime().after(twentyFourHoursAgo)) {
                return item;
            } else if (item.getReservationStatus().equals("pending")) {
                return item;
            }
            return null;
        }).collect(Collectors.toList());

//        List<RoomReservations> collect = roomReservations.stream().filter(item -> {
//            return item.getFullStartDateTime().after(twentyFourHoursAgo);
//        }).collect(Collectors.toList());

        List<EnableCancellReservationDTO> cancellReservationDTOS = collect.stream().map(item -> {
            EnableCancellReservationDTO enableCancellReservationDTO = new EnableCancellReservationDTO();
            if(item != null){
                enableCancellReservationDTO.setReservationId(item.getReservationId());
                MeetingRooms room = meetingRoomsMapper.selectOne(new QueryWrapper<MeetingRooms>().eq("room_id", item.getRoomId()));
                enableCancellReservationDTO.setRoomName(room.getName());
                enableCancellReservationDTO.setReservationDate(item.getReservationDate());
                enableCancellReservationDTO.setStartTime(item.getStartTime());
                enableCancellReservationDTO.setEndTime(item.getEndTime());
                enableCancellReservationDTO.setParticipants(item.getParticipants());
                enableCancellReservationDTO.setRequiredEquipment(item.getRequiredEquipment());
                enableCancellReservationDTO.setReservationStatus(item.getReservationStatus());
                enableCancellReservationDTO.setHourlyRentalPrice(room.getHourlyRentalPrice());
                return enableCancellReservationDTO;
            }
            return null;
        }).collect(Collectors.toList());

        return ResultVO.success(null, cancellReservationDTOS);
    }

    // 每分钟检查一次，删除超时订单
    @Scheduled(cron = "0 */1 * * * ?")
    public void checkExpiredPayments() {
        // 查询所有超时未支付的订单
        List<RoomReservations> expiredReservations = roomReservationsMapper.selectExpiredReservations(
                "pending",
                new Date()
        );
        for (RoomReservations reservation : expiredReservations) {
            roomReservationsMapper.delete(new QueryWrapper<RoomReservations>().eq("reservation_id", reservation.getReservationId()));
        }
    }

    @Override
    public ResultVO<List<RoomReservations>> getHistoryReservationsByID(Integer Id) {
        List<RoomReservations> reservations = roomReservationsMapper.selectList(new QueryWrapper<RoomReservations>().eq("user_id", Id));
        return ResultVO.success("获取历史预定成功", reservations);
    }

    @Override
    public ResultVO getTotalPrice(String reservationId) {
        RoomReservations roomReservations = roomReservationsMapper.selectOne(new QueryWrapper<RoomReservations>().eq("reservation_id", reservationId));
        Double hours = roomReservations.getDurationHours();
        MeetingRooms roomId = meetingRoomsMapper.selectOne(new QueryWrapper<MeetingRooms>().eq("room_id", roomReservations.getRoomId()));
        BigDecimal pay = roomId.getHourlyRentalPrice().multiply(BigDecimal.valueOf(hours));
        System.out.println("需要支付：" + pay + "元");
        return ResultVO.success("获取总价成功", pay);
    }

}